package com.wuliu.interceptor;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.wuliu.common.annotation.NoAuth;
import com.wuliu.common.constant.CacheConstants;
import com.wuliu.common.constant.Constants;
import com.wuliu.common.core.domain.ApiResult;
import com.wuliu.common.core.redis.RedisCache;
import com.wuliu.common.utils.ThreadLocalContext;
import com.wuliu.common.core.domain.entity.SysAppletUser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * @author realue
 * @version 1.0
 * @date 2022-10-12 17:26
 */
@Slf4j
@Component
public class AppInterceptor implements HandlerInterceptor {

    private static final String TOKEN_KEY = "token";

    @Resource
    private RedisCache redisCache;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/html; charset=utf-8");
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        if (handlerMethod.hasMethodAnnotation(NoAuth.class)) {
            return true;
        }
        String token = request.getHeader(TOKEN_KEY);
        ApiResult apiResult = null;
        if (StrUtil.isNotEmpty(token)) {
            String sysUsers = redisCache.getCacheObject(CacheConstants.TOKEN_SYS_USER_LOGIN_INFO_KEY + token);
            if (StrUtil.isNotEmpty(sysUsers)) {
                SysAppletUser sysUser = JSONUtil.toBean(sysUsers, SysAppletUser.class);
                //存threadLocal
                ThreadLocalContext.bindSysUser(sysUser);
                //刷新token
                redisCache.setCacheObject(CacheConstants.TOKEN_SYS_USER_LOGIN_INFO_KEY + token, sysUsers, Constants.APP_TOKEN_EXPIRE_TIME, TimeUnit.DAYS);
            } else {
                apiResult = ApiResult.error("用户登录信息已过期");
            }
        } else {
            apiResult = ApiResult.error("用户token不能为空");
        }
        if (apiResult != null) {
            log.error("登录失败,apiResult={}", JSONUtil.toJsonStr(apiResult));
            response.getWriter().print(JSONUtil.toJsonStr(apiResult));
            return false;
        }
        return true;
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        ThreadLocalContext.unBindSysUser();
    }
}
